package io.feige.rpc.consumer.handler;

import io.feige.rpc.consumer.RpcConsumerService;
import io.feige.rpc.consumer.cluster.LoadBalance;
import io.feige.rpc.consumer.cluster.implement.DefaultLoadBalanceImpl;
import io.feige.rpc.consumer.config.RemoteServiceConfig;
import io.feige.rpc.consumer.config.ServiceSocketAddress;
import io.feige.rpc.exception.NoServiceFoundException;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class ClientInvokerHandler implements InvocationHandler {
 
	private LoadBalance loadBalance;
	
	private String servcie;
 
	private RpcConsumerService rpcConsumerService; 
	
	public ClientInvokerHandler(RpcConsumerService rpcConsumerService, String servcie) {
		this.rpcConsumerService=rpcConsumerService;
		this.servcie=servcie;
		loadBalance=new DefaultLoadBalanceImpl(rpcConsumerService);
	}

	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Class<?>[] types = method.getParameterTypes(); 
		RemoteServiceConfig config=rpcConsumerService.getRemoteServiceConfigManager().getrRemoteServiceConfig(servcie);
		if (config==null) {
			throw new NoServiceFoundException(servcie);
		}
		ServiceSocketAddress sa=loadBalance.select(config.getHosts());
		if (sa==null) {
			throw new NoServiceFoundException();
		}
		return rpcConsumerService.getConnectionService().write(sa, servcie, method.getName(), types, args, config.getTimeout());
	}
 
}
